package DEEPERsource.DEEPERsource.source.parser.stanfordparser.JUNGadapter;

import edu.stanford.nlp.ling.MapLabel;
import edu.stanford.nlp.trees.TypedDependency;
import edu.uci.ics.jung.graph.DirectedEdge;
import edu.uci.ics.jung.graph.Vertex;
import edu.uci.ics.jung.graph.impl.DirectedSparseEdge;
import edu.uci.ics.jung.utils.UserData;
import graph.Keys;
import jung.entities.Graph;
import jung.entities.DependencyVertex;

/**
 * Local builder isolates JUNG-specific graph building logic 
 * 
 * @author tfayruzo
 *
 */
class DependencyTreeBuilder implements Keys{
	private Graph depTree;
	private int edgeIndex;
	
	public void init(){
		depTree = new Graph();
		edgeIndex = 0;
	}
	
	public void init(Graph graph){
		depTree = graph;
	}
	
	public void add(TypedDependency dependency){
		Vertex gov = new DependencyVertex();
		gov.addUserDatum(LABEL, dependency.gov().label().value(), UserData.SHARED);
		int ind = dependency.gov().index();
		//in the dependency tree the labels are duplpicated sometimes, and 
		//we need to take it into account
		//This solution is quite stupid, but I couldn't come up with a better idea...
		if(((MapLabel)dependency.gov().label()).get("copy").equals("true")){
			ind +=1000;
		}
		gov.addUserDatum(INDEX, ind, UserData.SHARED);
		
		Vertex dep = new DependencyVertex();
		dep.addUserDatum(LABEL, dependency.dep().label().value(), UserData.SHARED);
		ind = dependency.dep().index();
		if(((MapLabel)dependency.dep().label()).get("copy").equals("true")){
			ind +=1000;
		}
		dep.addUserDatum(INDEX, ind, UserData.SHARED);
		
		String edgeLabel = dependency.reln().toString();
		DependencyVertex _gov = (DependencyVertex)depTree.findVertex(gov);
		DependencyVertex _dep = (DependencyVertex)depTree.findVertex(dep);
		DirectedEdge e = null;
		if(_gov != null && _dep!=null){
			//sanity check, whether the edge already exists in the graph
			for(Object edge : depTree.getEdges()){
				if(_gov.isSame((DependencyVertex)((DirectedEdge)edge).getSource())&&
						_dep.isSame((DependencyVertex)((DirectedEdge)edge).getDest())){
					if(((DirectedEdge)edge).getUserDatum(LABEL).equals(edgeLabel)){
						(new RuntimeException("Trying to add edge "+edgeLabel+" twice")).printStackTrace();
						return;
					}
				}
			}
			e = new DirectedSparseEdge(_gov, _dep);			
		}else if(_gov != null){
			depTree.addVertex(dep);
			e = new DirectedSparseEdge(_gov, dep);			
		}else if(_dep != null){
			depTree.addVertex(gov);
			e = new DirectedSparseEdge(gov, _dep);			
		}else{
			depTree.addVertex(dep);
			depTree.addVertex(gov);
			e = new DirectedSparseEdge(gov, dep);
		}
		e.setUserDatum(LABEL, edgeLabel, UserData.SHARED);
		e.setUserDatum(INDEX, edgeIndex++, UserData.SHARED);
		depTree.addEdge(e);
	}
	
	public Graph getDepTree() {
		return depTree;
	}
}
